/*
 * (C) APUE
 * Use mutex to protect data structure
 */
#include <stdlib.h>
#include <pthread.h>

struct foo
{
	int f_count;
	pthread_mutex_t f_lock;
	/* more stuff here */
};

/* allocate the object */
struct foo* foo_alloc(void)
{
	struct foo *fp;
	if ((fp = malloc(sizeof(struct foo))) != NULL)
	{
		fp->f_count = 1;
		if (pthread_mutex_init(&fp->f_lock, NULL) != 0)
		{
		       free(fp);
		       return (NULL);
		}
		/* continue other initialization */
	}

	return (fp);
}

/* add a reference to the object */
void foo_hold(struct foo *fp)
{
	pthread_mutex_lock(&fp->f_lock);
	fp->f_count++;
	pthread_mutex_unlock(&fp->f_lock);
}

/* release a reference to the object */
void foo_rele(struct foo *fp)
{
	pthread_mutex_lock(&fp->f_lock);
	if (--fp->f_count == 0)	/* last reference */
	{
		pthread_mutex_unlock(&fp->f_lock);	/* some problem here ? */
		/* what will happen when other thread call foo_hold() here ? */
		pthread_mutex_destroy(&fp->f_lock);
		free(fp);
	}
	else
		pthread_mutex_unlock(&fp->f_lock);
}
